package com.joe.framework.config;

import lombok.extern.log4j.Log4j2;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.FlywayException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

/**
 * 将flyway配置从springboot排除，避免springboot自动配置
 * @SpringBootApplication(exclude = { FlywayAutoConfiguration.class })
 * 如果存在加载顺序问题可使用Spring @DependsOn控制bean加载顺序
 * @DependsOn("flywayConfig")
 *
 * 1, 生产务必禁 spring.flyway.cleanDisabled=false 。
 *
 * 2, 尽量避免使用 Undo 模式。
 *
 * 3, 开发版本号尽量根据团队来进行多层次的命名避免混乱。
 *    比如 V1.0.1__ProjectName_{Feature|fix}_Developer_Description.sql
 *    这种命名同时也可以获取更多脚本的开发者和相关功能的信息。
 *
 * 4, spring.flyway.outOfOrder 取值 生产上使用 false，开发中使用 true。
 *
 * 5, 多个系统公用一个 数据库 schema 时配置spring.flyway.table 为不同的系统设置
 *    不同的 metadata 表名而不使用缺省值 flyway_schema_history 。
 */

@Configuration
@Log4j2
public class FlywayConfig {

    @Autowired
    private DataSource dataSource;

    @PostConstruct
    public void migrate()  {
        Flyway flyway = new Flyway();
        flyway.setDataSource(dataSource);
        // 设置flyway扫描sql升级脚本、java升级脚本的目录路径或包路径（表示是src/main/resources/flyway下面，前缀默认为src/main/resources，因为这个路径默认在classpath下面）
        flyway.setLocations("classpath:sql/migration");
        // 设置sql脚本文件的编码
        flyway.setEncoding("UTF-8");
        // 生产上使用 false，开发中使用 true。
        flyway.setOutOfOrder(true);

        try {
            flyway.migrate();
        } catch (FlywayException e) {
            flyway.repair();
            log.error("Flyway配置加载出错",e);
        }
    }
}